package com.yanqu.road.server.gameplayer.module.activity.deepseafishing;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.UserActivityConditionData;
import com.yanqu.road.entity.activity.deepfishing.DeepFishingUserData;
import com.yanqu.road.entity.activity.deepfishing.DeepFishingUserFishData;
import com.yanqu.road.entity.activity.deepfishing.config.DeepFishingConfig;
import com.yanqu.road.entity.activity.deepfishing.config.DeepFishingEquipConfig;
import com.yanqu.road.entity.activity.deepfishing.config.DeepFishingEventConfig;
import com.yanqu.road.entity.activity.deepfishing.config.DeepFishingFishConfig;
import com.yanqu.road.entity.activity.deepfishing.entity.DeepFishingBagItemData;
import com.yanqu.road.entity.activity.deepfishing.entity.DeepFishingBeachCombItemData;
import com.yanqu.road.entity.activity.deepfishing.entity.DeepFishingCalValueAndWeight;
import com.yanqu.road.entity.activity.deepfishing.entity.DeepFishingFishingCheckPoint;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.enums.activity.deepfishing.eDeepFishRodPartType;
import com.yanqu.road.entity.enums.activity.deepfishing.eDeepFishingBuffType;
import com.yanqu.road.entity.enums.activity.deepfishing.eDeepFishingEventType;
import com.yanqu.road.entity.enums.activity.deepfishing.eDeepFishingObjectType;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.log.LogDeepFishingBeachComb;
import com.yanqu.road.entity.log.LogDeepFishingFishing;
import com.yanqu.road.entity.log.LogDeepFishingRodUpdate;
import com.yanqu.road.logic.bussiness.activity.DeepFishingBusiness;
import com.yanqu.road.logic.helper.CalcPowerResult;
import com.yanqu.road.logic.helper.PowerHelper;
import com.yanqu.road.pb.activity.DeepFishingProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.ActivityModule;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.logic.activity.BaseActivityData;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.deepfishing.DeepFishingMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.pb.DeepFishingPb;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class DeepFishingModule extends GeneralModule {

    private DeepFishingUserData userData;

    private List<DeepFishingFishingCheckPoint> checkPointList = new ArrayList<>();

    private Map<Integer, DeepFishingUserFishData> userFishDataMap;

    private Random random;

    public DeepFishingModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        ActivityInfo activityInfo = DeepFishingMgr.getActivityInfo();
        if (activityInfo !=null){
            userData = DeepFishingBusiness.getDeepFishingUserData(activityInfo.getActivityId(),getUserId());
            userFishDataMap = DeepFishingBusiness.getDeepFishingUserFishDataMap(activityInfo.getActivityId(),getUserId());
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return false;
    }

    @Override
    public boolean saveData() {
        if (null != userData) {
            if (userData.isInsertOption()){
                DeepFishingBusiness.addDeepFishingUserData(userData);
            }else if (userData.isUpdateOption()){
                DeepFishingBusiness.updateDeepFishingUserData(userData);
            }
        }
        if (userFishDataMap != null){
            for (DeepFishingUserFishData fishData:userFishDataMap.values()){
                if (fishData.isInsertOption()){
                    DeepFishingBusiness.addDeepFishingUserFishData(fishData);
                }else if (fishData.isUpdateOption()){
                    DeepFishingBusiness.updateDeepFishingUserFishData(fishData);
                }
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        syncFishingConfig();
        syncFishingData();
        syncBeachCombData();
        syncAllFishAtlasData();
    }

    /**
     * 初始化玩家鱼类图鉴数据
     */
    public void initUserFishAtlasData(){
        ActivityInfo activityInfo = DeepFishingMgr.getActivityInfo();
        if (activityInfo == null){
            return;
        }
        DeepFishingConfig config = DeepFishingMgr.getConfig();
        if (config == null){
            return;
        }
        if (userFishDataMap != null && !userFishDataMap.isEmpty()){    //如果不为空
            for (DeepFishingUserFishData fishData:userFishDataMap.values()){
                if (fishData.getActivityId() == activityInfo.getActivityId()){//并且为本次活动的数据
                    return;
                }
            }
        }
        Map<Integer, DeepFishingUserFishData> tmpUserFishData = new ConcurrentHashMap<>();
        for (DeepFishingFishConfig fishConfig:config.getFishConfigMap().values()){
            if (fishConfig.getType() == eDeepFishingObjectType.fish.getValue()||fishConfig.getType() == eDeepFishingObjectType.beachCombItem.getValue()){
                DeepFishingUserFishData fishData = new DeepFishingUserFishData();
                fishData.setFishId(fishConfig.getObjectId());
                fishData.setActivityId(activityInfo.getActivityId());
                fishData.setNum(0);
                fishData.setIsReadSample(false);
                fishData.setUserId(getUserId());
                fishData.setHeaviestWeight(0);
                fishData.setInsertOption();
                tmpUserFishData.put(fishData.getFishId(),fishData);
            }
        }
        userFishDataMap = tmpUserFishData;

    }


    /**
     * 初始化玩家基本数据
     */
    public void initUserData(){
        ActivityInfo activityInfo = DeepFishingMgr.getActivityInfo();
        //检测解锁
        if (!SystemOpenMgr.systemOpen(player,eSystemId.DeepFishing.getValue())){
            return;
        }
        if (activityInfo == null){
            return;
        }
        DeepFishingConfig config = DeepFishingMgr.getConfig();
        if (config == null){
            return;
        }
        if (userData != null && userData.getActivityId() == DeepFishingMgr.getActivityInfo().getActivityId()){
            return;
        }
        long now = System.currentTimeMillis();
        DeepFishingUserData tmpUserData = new DeepFishingUserData();
        tmpUserData.setActivityId(activityInfo.getActivityId());
        tmpUserData.setUserId(getUserId());
        tmpUserData.setBeachCombLevel(1);
        tmpUserData.setBeachCombLastRefreshTime(now);

        int randomSpecialTime = DeepFishingMgr.getRandomSpecialTime();
        tmpUserData.setBeachCombSpecialThisLevel(randomSpecialTime);
        tmpUserData.setBeachCombHasSpecialThisLevel(0);

        Map<Integer, DeepFishingBeachCombItemData> beachCombItemDataMap = DeepFishingMgr.generateCombItemMap(1,randomSpecialTime);
        tmpUserData.setBeachCombMap(beachCombItemDataMap);

        tmpUserData.setBeachCombPower(config.getDayFreeBeachCombTime());
        tmpUserData.setLastRecoveryBeachCombPowerTime(now);
        tmpUserData.setFishingReachMaxMeter(0);
        tmpUserData.setFishingBuffMap(new ConcurrentHashMap<>());
        tmpUserData.setFishingRodParts(generateOriginalFishingRodPartMap());
        tmpUserData.setFishingCoins(0);
        tmpUserData.setFishingPower(config.getFishingPowerMax());
        tmpUserData.setLastRecoveryFishingPowerTime(now);
        tmpUserData.setFishingGameStatus(0);
        tmpUserData.setNoBuffBiggestCoin(0);
        tmpUserData.setBestAutoRecord(new ArrayList<>());
        tmpUserData.setScoreThisActivity(0);
        tmpUserData.setInsertOption();
        userData = tmpUserData;

    }

    /**
     * 一键钓鱼
     */
    public int oneKeyFishing(int activityId){
        ActivityInfo activityInfo = DeepFishingMgr.getActivityInfo();
        if (activityInfo == null){
            return GameErrorCode.E_DEEP_FISHING_NO_OPEN;
        }
        if (activityInfo.getActivityId() != activityId){
            return GameErrorCode.E_DEEP_FISHING_NO_OPEN;
        }
        if (!ActivityMgr.activityInTime(activityInfo)){
            return GameErrorCode.E_DEEP_FISHING_NO_OPEN;
        }
        DeepFishingConfig config = DeepFishingMgr.getConfig();
        if(config==null){
            return GameErrorCode.E_DEEP_FISHING_CONFIG_ERROR;
        }
        //鱼竿等级不超过
        if (DeepFishingMgr.getDeepFishingEquipConfig(userData.getFishingRodParts().get(eDeepFishRodPartType.fishRod.getValue())).getLv() < DeepFishingMgr.getConfig().getAutoRodLevelNeed()){
            return GameErrorCode.E_DEEP_FISHING_ONE_KEY_ROD_NO_ENOUGH;
        }
        //最好记录为空
        List<DeepFishingBagItemData> bestAutoRecode = userData.getBestAutoRecord();
        if (bestAutoRecode.isEmpty()){
            return GameErrorCode.E_DEEP_FISHING_ONE_KEY_NO_RECORD;
        }
        calFishingPower();
        List<Integer> useBuffList = new ArrayList<>();
        int realUsePower = 0;
        //先看看是不是免费
        int noPowerBuff = DeepFishingMgr.getBuffIdByType(eDeepFishingBuffType.powerFreeBuff.getValue());
        boolean isFree = false;
        if (userData.getFishingBuffMap().containsKey(noPowerBuff)){
            if (userData.getFishingBuffMap().get(noPowerBuff) > 0){
                isFree  = checkBuffAdd(noPowerBuff, useBuffList);
            }
        }

        //体力
        int fishingNeedPower = DeepFishingMgr.getFishingNeedPower(userData.getFishingRodParts().get(eDeepFishRodPartType.fishRod.getValue()));
        if (!isFree){
            //如果体力不够
            if (userData.getFishingPower() < fishingNeedPower){
                return GameErrorCode.E_DEEP_FISHING_FISHING_POWER_NO_ENOUGH;
            }
            realUsePower = fishingNeedPower;
            //体力
            userData.setFishingPower(userData.getFishingPower() - fishingNeedPower);
        }

        //最先随机一下龙王和宝箱吧
        List<Integer> eventList = DeepFishingMgr.randomEvent();
        List<Integer> realEventList = new ArrayList<>();
        String boxReward = "";
        String buffReward = "";
        for (int eventId :eventList){
            DeepFishingEventConfig eventConfig = config.getEventConfigMap().get(eventId);
            if (eventConfig == null){
                log.error("深海觅诊活动{},事件配置{}不存在",activityId,eventId);
                continue;
            }
            if (eventConfig.getLittle() == 0){
                continue;               //无事发生
            }
            if (eventConfig.getType() == eDeepFishingEventType.cycloneEvent.getValue()){
                continue;
            }
            realEventList.add(eventId);
            if (eventConfig.getType() == eDeepFishingEventType.boxEvent.getValue()){
                //随机并且加奖励
                Property BoxProperty = PropertyHelper.parseNewStringToProperty(eventConfig.getEventValue());
                BoxProperty.goodCountMultiNum(fishingNeedPower);
                player.getModule(CurrencyModule.class).addCurrency(BoxProperty, eLogMoneyType.DeepFishing,eLogMoneyType.DeepFishingEventBox);
                boxReward = PropertyHelper.parsePropertyToString(BoxProperty);
                continue;
            }
            if (eventConfig.getType() == eDeepFishingEventType.buffEvent.getValue()){
                if (eventConfig.getLittle() == (eDeepFishingBuffType.singleFishCoinAddBuff.getValue())){
                    String eventValue = eventConfig.getEventValue();
                    List<Integer> list = StringUtils.stringToIntegerList(eventValue, "\\|");
                    addBuffToUser(eventConfig.getEventId(),list.get(1));
                }else if (eventConfig.getLittle() == (eDeepFishingBuffType.scoreAddBuff.getValue())){
                    String eventValue = eventConfig.getEventValue();
                    List<Integer> list = StringUtils.stringToIntegerList(eventValue, "\\|");
                    addBuffToUser(eventConfig.getEventId(),list.get(1));
                }else if (eventConfig.getLittle() == (eDeepFishingBuffType.powerFreeBuff.getValue())){
                    String eventValue = eventConfig.getEventValue();
                    int times = StringUtils.parseInt(eventValue);
                    addBuffToUser(eventId,times);
                }

                buffReward = eventConfig.getEventId()+"";
            }
        }

        int noBuffScore = config.getFishingItemToScoreNum() * fishingNeedPower ;
        long totalCoin = 0;

        for (DeepFishingBagItemData fishingBagItemData : bestAutoRecode){
            int objectId = fishingBagItemData.getObjectId();
            DeepFishingFishConfig objectConfig = DeepFishingMgr.getObjectConfig(objectId);
            if (objectConfig == null){
                log.error("深海觅诊活动id{}物品{}配置不存在",activityId,objectId);
                continue;
            }
            if (objectConfig.getType() == eDeepFishingObjectType.fish.getValue()){
                totalCoin += fishingBagItemData.getValue();
                addFishRecordToAtlas(fishingBagItemData);
            }
            if (objectConfig.getType() == eDeepFishingObjectType.item.getValue()){
                totalCoin += fishingBagItemData.getValue();
            }

        }
        //鱼竿金币加成
        int rodCoinAddition = DeepFishingMgr.getRodCoinAdd(userData.getFishingRodParts());
        //buff金币加成
        int coinBuffAddRate = 0;
        int fishCoinAddBuffId = DeepFishingMgr.getBuffIdByType(eDeepFishingBuffType.singleFishCoinAddBuff.getValue());
        if (checkBuffAdd(fishCoinAddBuffId, useBuffList)){
            coinBuffAddRate = DeepFishingMgr.getBuffAddRate(eDeepFishingBuffType.singleFishCoinAddBuff.getValue());
        }
        //积分的buff加成
        int scoreBuffadd = 0;
        //score buff的总加成
        int buffIdByType = DeepFishingMgr.getBuffIdByType(eDeepFishingBuffType.scoreAddBuff.getValue());
        boolean scoreBuffAdd = checkBuffAdd(buffIdByType, useBuffList);
        if (scoreBuffAdd){
            String eventValue = config.getEventConfigMap().get(buffIdByType).getEventValue();
            scoreBuffadd += StringUtils.stringToIntegerList(eventValue,"\\|").get(0);
        }

        //结算金币和积分
        BigDecimal coinDecimal = BigDecimal.valueOf(totalCoin).multiply(BigDecimal.valueOf(rodCoinAddition))
                .divide(BigDecimal.valueOf(1000),1,BigDecimal.ROUND_DOWN)
                .multiply(BigDecimal.valueOf(1000+coinBuffAddRate)).divide(BigDecimal.valueOf(1000),0,BigDecimal.ROUND_DOWN);

        long resultCoin = coinDecimal.longValue();
        int resultScore = noBuffScore * (1000 + scoreBuffadd )/ 1000;

        //加金币
        userData.setFishingCoins(userData.getFishingCoins()+resultCoin);
        //金币成就 排行榜
        player.notifyListener(eGamePlayerEventType.DeepFishingTotalCoinRank.getValue(),resultCoin);
        player.notifyListener(eGamePlayerEventType.DeepFishingTotalCoinProcess.getValue(),resultCoin);

        Property scoreReward = new Property(DeepFishingMgr.getConfig().getScoreItemId(),resultScore);
        //加积分
        player.getModule(CurrencyModule.class).addCurrency(scoreReward,eLogMoneyType.DeepFishing,eLogMoneyType.DeepFishingFishingAdd);
        userData.setScoreThisActivity(userData.getScoreThisActivity() + resultScore);

        if (!isFree){
            //检测本次是否钓到了免费buff
            boolean checkResultFree = checkBuffAdd(noPowerBuff, useBuffList);
            if (checkResultFree){
                userData.setFishingPower(userData.getFishingPower()+fishingNeedPower);
                realUsePower = 0;
            }
        }

        LogDeepFishingFishing logDeepFishingFishing = new LogDeepFishingFishing(getUserId(),activityId,1,
                -1,userData.getFishingPower()+realUsePower,realUsePower,userData.getFishingPower(),bestAutoRecode,userData.getCacheEvent(),new HashMap<>(),
                new ArrayList<>(),"","",
                userData.getFishingRodParts(),resultCoin+"",PropertyHelper.parsePropertyToString(scoreReward),0,new Date());

        AutoLogMgr.add(logDeepFishingFishing);
        //回包
        DeepFishingProto.oneKeyFishingRespMsg.Builder builder = DeepFishingProto.oneKeyFishingRespMsg.newBuilder();
        builder.setRet(0);
        builder.setCoin(DeepFishingMgr.getConfig().getCoinItemId()+"="+resultCoin);
        builder.setScoreReward(PropertyHelper.parsePropertyToString(scoreReward));
        for (int buffId:useBuffList){
            builder.addBuffUsed(buffId);
        }
        builder.setBoxReward(boxReward);
        builder.setDragonEventReward(buffReward);
        builder.setPowerUsed(realUsePower);
        builder.addAllTriggerEvent(realEventList);
        player.sendPacket(ClientProtocol.U_DEEP_FISHING_ONE_KEY_FISHING,builder);
        syncFishingData();
        return 0;
    }

    /**
     * 消除图鉴红点
     */
    public void readAtlasSample(int activityId,int fishId){
        ActivityInfo activityInfo = DeepFishingMgr.getActivityInfo();
        if (activityInfo == null){
            return;
        }
        if (activityId != activityInfo.getActivityId()){
            return;
        }
        DeepFishingUserFishData fishData = userFishDataMap.get(fishId);
        if (fishData == null){
            return;
        }
        if (fishData.getNum() == 0){
            return;
        }
        if (!fishData.getIsReadSample()){
            fishData.setIsReadSample(true);
        }
        syncFishData(Collections.singletonList(fishData));
    }


    /**
     * 生成初始鱼竿配件
     * @return
     */

    public Map<Integer,Integer> generateOriginalFishingRodPartMap(){
        Map<Integer, DeepFishingEquipConfig> equipConfigMap = DeepFishingMgr.getConfig().getEquipConfigMap();
        Map<Integer,Integer> resultMap = new ConcurrentHashMap<>();
        for (DeepFishingEquipConfig equipConfig: equipConfigMap.values()){
            if(equipConfig.getLv() == 1){
                resultMap.put(equipConfig.getType(),equipConfig.getLvId());
            }
        }
        return resultMap;
    }


    /**
     * 升级鱼竿
     */
    public int levelUpFishingRod(int activityId,int type){
        ActivityInfo activityInfo = DeepFishingMgr.getActivityInfo();
        if (activityInfo == null){
            return GameErrorCode.E_DEEP_FISHING_NO_OPEN;
        }
        if (activityInfo.getActivityId()!=activityId){
            return GameErrorCode.E_DEEP_FISHING_NO_OPEN;
        }
        if (!userData.getFishingRodParts().containsKey(type)){
            return GameErrorCode.E_DEEP_FISHING_ROD_CONFIG_ERROR;
        }
        int oldLevelId = userData.getFishingRodParts().get(type);
        DeepFishingEquipConfig deepFishingEquipConfig = DeepFishingMgr.getDeepFishingEquipConfig(oldLevelId);
        if (deepFishingEquipConfig == null){
            return GameErrorCode.E_DEEP_FISHING_ROD_CONFIG_ERROR;
        }
        int cost = deepFishingEquipConfig.getCost();
        if (cost == 0){
            return GameErrorCode.E_DEEP_FISHING_ROD_LEVEL_MAX;
        }
        if (userData.getFishingCoins() < cost){
            return GameErrorCode.E_DEEP_FISHING_COIN_NO_ENOUGH;
        }

        DeepFishingEquipConfig nextLevelEquipConfig = DeepFishingMgr.getNextLevelEquipConfig(oldLevelId);
        if (nextLevelEquipConfig == null){
            return GameErrorCode.E_DEEP_FISHING_ROD_LEVEL_MAX;
        }
        int userEquipTotalLevel = getUserEquipTotalLevel();
        if (nextLevelEquipConfig.getType()==eDeepFishRodPartType.fishRod.getValue()||nextLevelEquipConfig.getType()==eDeepFishRodPartType.fishHook.getValue()){
            if (nextLevelEquipConfig.getEffectValue().get(2)>userEquipTotalLevel){
                return GameErrorCode.E_DEEP_FISHING_ROD_LEVEL_NO_ENOUGH;
            }
        }
        if (nextLevelEquipConfig.getType()==eDeepFishRodPartType.fishFood.getValue()){
            if (nextLevelEquipConfig.getEffectValue().get(1)>userEquipTotalLevel){
                return GameErrorCode.E_DEEP_FISHING_ROD_LEVEL_NO_ENOUGH;
            }
        }


        long coinBefore = userData.getFishingCoins();
        userData.setFishingCoins(userData.getFishingCoins()-cost);
        long coinAfter = userData.getFishingCoins();

        userData.getFishingRodParts().put(type,nextLevelEquipConfig.getLvId());

        DeepFishingProto.deepFishingUpgradeFishRodPartRespMsg.Builder builder = DeepFishingProto.deepFishingUpgradeFishRodPartRespMsg.newBuilder();
        builder.setRet(0);
        for (Map.Entry<Integer,Integer> entry:userData.getFishingRodParts().entrySet()){
            DeepFishingProto.deepFishingRodParts.Builder equipBuilder = DeepFishingProto.deepFishingRodParts.newBuilder();
            equipBuilder.setPartId(entry.getKey());
            equipBuilder.setLevel(entry.getValue());
            builder.addNewParts(equipBuilder);
        }
        builder.setCoinNow(userData.getFishingCoins());
        LogDeepFishingRodUpdate logDeepFishingRodUpdate = new LogDeepFishingRodUpdate(getUserId(),activityId,cost,type,oldLevelId,nextLevelEquipConfig.getLvId(),coinBefore,coinAfter,new Date());
        AutoLogMgr.add(logDeepFishingRodUpdate);
        player.sendPacket(ClientProtocol.U_DEEP_FISHING_UPGRADE_FISH_ROD_PART,builder);
        return 0;
    }

    public int getUserEquipTotalLevel(){
        if (userData == null){
            return 0;
        }
        if (userData.getFishingRodParts()==null){
            return 0;
        }
        int totalLevel = 0;
        for (int partLevelId:userData.getFishingRodParts().values()){
            DeepFishingEquipConfig deepFishingEquipConfig = DeepFishingMgr.getDeepFishingEquipConfig(partLevelId);
            if (deepFishingEquipConfig!=null){
                totalLevel+=deepFishingEquipConfig.getLv();
            }
        }
        return totalLevel;
    }

    /**
     * 钓鱼开始
     */
    public int startFishingGame(int activityId){
        ActivityInfo activityInfo = DeepFishingMgr.getActivityInfo();
        if (activityInfo == null){
            return GameErrorCode.E_DEEP_FISHING_NO_OPEN;
        }
        if (activityInfo.getActivityId() != activityId){
            return GameErrorCode.E_DEEP_FISHING_NO_OPEN;
        }

        if (!ActivityMgr.activityInTime(activityInfo)){
            return GameErrorCode.E_DEEP_FISHING_NO_OPEN;
        }

        if (userData == null){
            return GameErrorCode.E_DEEP_FISHING_NO_OPEN;
        }
        //先计算体力一下
        calFishingPower();
        int rodLevel = userData.getFishingRodParts().get(1);
        int powerNeed = DeepFishingMgr.getFishingNeedPower(rodLevel);
        int noPowerBuff = DeepFishingMgr.getBuffIdByType(eDeepFishingBuffType.powerFreeBuff.getValue());
        boolean isFree = false;
        if (userData.getFishingBuffMap().containsKey(noPowerBuff)){
            if (userData.getFishingBuffMap().get(noPowerBuff) > 0){
                isFree = true;
            }
        }
        if (!isFree){
            if (userData.getFishingPower() < powerNeed){
                return GameErrorCode.E_DEEP_FISHING_FISHING_POWER_NO_ENOUGH;
            }
        }
        List<Integer> list = DeepFishingMgr.randomEvent();
        userData.setCacheEvent(list);
        userData.setFishingGameStatus(1);       //设置为开始状态
        checkPointList = new ArrayList<>();     //清空检测
        DeepFishingProto.deepFishingStartRespMsg.Builder builder = DeepFishingProto.deepFishingStartRespMsg.newBuilder();
        builder.setRet(0);
        for (int eventId:list){
            builder.addEventId(eventId);
        }
        player.sendPacket(ClientProtocol.U_DEEP_FISHING_START_GAME,builder);
        return 0;
    }

    /**
     * 钓鱼途中检测
     */
    public int checkFishingProcess(DeepFishingFishingCheckPoint checkPoint){
        if (checkPoint == null){
            return GameErrorCode.E_DEEP_FISHING_CHECK_POINT_ERROR;
        }
        int originSpeed = DeepFishingMgr.getConfig().getFishingDownSpeed();
        int hookId = userData.getFishingRodParts().get(eDeepFishRodPartType.fishHook.getValue());
        DeepFishingEquipConfig deepFishingEquipConfig = DeepFishingMgr.getDeepFishingEquipConfig(hookId);
        if (deepFishingEquipConfig == null){
            return GameErrorCode.E_DEEP_FISHING_CONFIG_ERROR;
        }
        int hookadd = deepFishingEquipConfig.getEffectValue().get(0);
        int speecCheckAdd = DeepFishingMgr.getConfig().getSpeecCheckAdd();
        int maxSpeed =  originSpeed / 1000 * (1000+hookadd) / 1000 * speecCheckAdd  / 1000;
        synchronized (checkPointList){
            checkPointList.add(checkPoint);
            checkPointList.sort(Comparator.comparing(DeepFishingFishingCheckPoint::getTimeMill));
            return checkAllFishingPoint(maxSpeed);
        }
    }

    /**
     * 检测所有点
     * @return
     */

    private int checkAllFishingPoint(int maxSpeed){
        if (checkPointList.size()>1){
            for (int i = 1;i <checkPointList.size();i++){
                int checkResult = checkAdjacentTwoPoint(checkPointList.get(i - 1), checkPointList.get(i),maxSpeed);
                if (checkResult != 0){
                    return checkResult;
                }
            }
        }
        return 0;

    }

    private int checkAdjacentTwoPoint(DeepFishingFishingCheckPoint beforePoint,DeepFishingFishingCheckPoint afterPoint,int maxSpeed){
        long timeMillDiff = afterPoint.getTimeMill() - beforePoint.getTimeMill();
        long deepDiff = afterPoint.getDeep() - beforePoint.getDeep();
        //越钓越上面了还
//        if (deepDiff < 0){
//            return GameErrorCode.E_DEEP_FISHING_CHECK_POINT_ERROR;
//        }
//        if (deepDiff > 100){
//            return GameErrorCode.E_DEEP_FISHING_CHECK_POINT_ERROR;
//        }
//        long secondDiff = timeMillDiff / DateHelper.SECOND_MILLIONS;
//        long maxDisTance = secondDiff * maxSpeed;
//        long secondDiff = timeMillDiff / DateHelper.SECOND_MILLIONS;
        BigDecimal maxDistance = BigDecimal.valueOf(timeMillDiff).multiply(BigDecimal.valueOf(maxSpeed)).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_UP);
        long maxDisTance = maxDistance.longValue();
        if (deepDiff > maxDisTance){
            return GameErrorCode.E_DEEP_FISHING_CHECK_POINT_ERROR;
        }
        return 0;
    }

    /**
     * 钓鱼结算
     */
    public int fishSettlement(int activityId,List<DeepFishingBagItemData> bagResultList,Map<Integer,Integer> eventMap,int deep){
        ActivityInfo activityInfo = DeepFishingMgr.getActivityInfo();
        if (activityInfo == null){
            return GameErrorCode.E_DEEP_FISHING_NO_OPEN;
        }
        if (activityInfo.getActivityId() != activityId){
            return GameErrorCode.E_DEEP_FISHING_ACTIVITY_ID_ERROR;
        }
        DeepFishingConfig config = DeepFishingMgr.getConfig();
        if(config==null){
            return GameErrorCode.E_DEEP_FISHING_CONFIG_ERROR;
        }
        if (!ActivityMgr.activityInTime(activityInfo)){
            return GameErrorCode.E_DEEP_FISHING_NO_OPEN;
        }
        //先给一个log
        LogDeepFishingFishing logDeepFishingFishing = new LogDeepFishingFishing(getUserId(),activityId,0,
                1,userData.getFishingPower(),0,0,bagResultList,userData.getCacheEvent(),eventMap,
                new ArrayList<>(),"","",
                userData.getFishingRodParts(),"","",deep,new Date());


        Map<Integer, DeepFishingFishConfig> fishConfigMap = config.getFishConfigMap();
        //判断发生事件是否在开局生成的数组内
        for (int eventId:eventMap.keySet()){
            if (!userData.getCacheEvent().contains(eventId)){       //可能是数据错 可能是玩家掉线太久了
                logDeepFishingFishing.setIsSuccess(GameErrorCode.E_DEEP_FISHING_TRIGGER_EVENT_ERROR);
                AutoLogMgr.add(logDeepFishingFishing);              //不成功也log一下
                return GameErrorCode.E_DEEP_FISHING_TRIGGER_EVENT_ERROR;
            }
        }
//        if (checkPointList.isEmpty()){
//            log.debug("深海觅诊活动:{}玩家id:{}过程点为空",activityId,getUserId());
//            logDeepFishingFishing.setIsSuccess(GameErrorCode.E_DEEP_FISHING_CHECK_POINT_ERROR);
//            AutoLogMgr.add(logDeepFishingFishing);              //不成功也log一下
//            return GameErrorCode.E_DEEP_FISHING_CHECK_POINT_ERROR;
//        }
        int bagMaxCapacity = DeepFishingMgr.getBagMaxCapacity(userData.getFishingRodParts());
        if (bagResultList.size() > bagMaxCapacity){
            logDeepFishingFishing.setIsSuccess(GameErrorCode.E_DEEP_FISHING_TRIGGER_EVENT_ERROR);
            AutoLogMgr.add(logDeepFishingFishing);              //不成功也log一下
            return GameErrorCode.E_DEEP_FISHING_TRIGGER_EVENT_ERROR;
        }
        int rodLevelid = userData.getFishingRodParts().get(eDeepFishRodPartType.fishRod.getValue());
        //检测鱼鱼
        int isRight = DeepFishingMgr.checkResultRight(bagResultList,deep,getUserId(),eventMap,rodLevelid);
        if (isRight != 0){
            logDeepFishingFishing.setIsSuccess(isRight);
            AutoLogMgr.add(logDeepFishingFishing);              //不成功也log一下
            return isRight;
        }
        //所有加成的buff
        List<Integer> hasBuffList = new ArrayList<>();

        //体力需求检测
        int needPower = DeepFishingMgr.getFishingNeedPower(rodLevelid);
        logDeepFishingFishing.setPowerUsed(needPower);
        //先看看是不是免费
        int noPowerBuff = DeepFishingMgr.getBuffIdByType(eDeepFishingBuffType.powerFreeBuff.getValue());
        boolean isFree = false;
        if (userData.getFishingBuffMap().containsKey(noPowerBuff)){
            if (userData.getFishingBuffMap().get(noPowerBuff) > 0){
                isFree  = checkBuffAdd(noPowerBuff, hasBuffList);
            }
        }
        if (!isFree){
            //如果体力不够
            if (userData.getFishingPower() < needPower){
                logDeepFishingFishing.setPowerAfter(userData.getFishingPower());
                logDeepFishingFishing.setIsSuccess(GameErrorCode.E_DEEP_FISHING_FISHING_POWER_NO_ENOUGH);
                AutoLogMgr.add(logDeepFishingFishing);              //不成功也log一下
                return GameErrorCode.E_DEEP_FISHING_FISHING_POWER_NO_ENOUGH;
            }
            userData.setFishingPower(userData.getFishingPower() - needPower);
            logDeepFishingFishing.setPowerAfter(userData.getFishingPower());

        } else {
            logDeepFishingFishing.setPowerAfter(userData.getFishingPower());
        }
        logDeepFishingFishing.setIsSuccess(1);
        userData.setFishingGameStatus(0);
        //返回值
        DeepFishingProto.deepFishingGameSettlementRespMsg.Builder respBuilder = DeepFishingProto.deepFishingGameSettlementRespMsg.newBuilder();
        //先计算一下这把获得的事件
        for (int eventId:eventMap.keySet()){
            DeepFishingEventConfig eventConfig = config.getEventConfigMap().get(eventId);
            if (eventConfig == null){
                log.error("深海觅诊活动{},事件配置{}不存在",activityId,eventId);
                continue;
            }
            if (eventConfig.getLittle() == 0){
                continue;               //无事发生
            }
            if (eventConfig.getType() == eDeepFishingEventType.boxEvent.getValue()){
                //随机并且加奖励
                Property property = PropertyHelper.parseNewStringToProperty(eventConfig.getEventValue());
                property.goodCountMultiNum(needPower);
                logDeepFishingFishing.setBoxReward(PropertyHelper.parsePropertyToString(property));
                player.getModule(CurrencyModule.class).addCurrency(property, eLogMoneyType.DeepFishing,eLogMoneyType.DeepFishingEventBox);
                respBuilder.setBoxReward(PropertyHelper.parsePropertyToString(property));
                continue;
            }
            if (eventConfig.getType() == eDeepFishingEventType.buffEvent.getValue()){
                if (eventConfig.getLittle() == (eDeepFishingBuffType.singleFishCoinAddBuff.getValue())){
                    String eventValue = eventConfig.getEventValue();
                    List<Integer> list = StringUtils.stringToIntegerList(eventValue, "\\|");
                    addBuffToUser(eventConfig.getEventId(),list.get(1));
                    logDeepFishingFishing.setBuffReward(eventConfig.getEventId()+"="+list.get(1));
                }else if (eventConfig.getLittle() == (eDeepFishingBuffType.scoreAddBuff.getValue())){
                    String eventValue = eventConfig.getEventValue();
                    List<Integer> list = StringUtils.stringToIntegerList(eventValue, "\\|");
                    addBuffToUser(eventConfig.getEventId(),list.get(1));
                    logDeepFishingFishing.setBuffReward(eventConfig.getEventId()+"="+list.get(1));
                }else if (eventConfig.getLittle() == (eDeepFishingBuffType.powerFreeBuff.getValue())){
                    String eventValue = eventConfig.getEventValue();
                    int times = StringUtils.parseInt(eventValue);
                    addBuffToUser(eventId,times);
                    logDeepFishingFishing.setBuffReward(eventConfig.getEventId()+"="+times);
                }

                respBuilder.setDragonEventReward(eventConfig.getEventId()+"");
            }
        }
        //所有鱼和物品的初始金币
        int originalCoin = 0;
        //开始游戏就有的积分
        int originalOpenScore = config.getFishingItemToScoreNum() * needPower;

        //先计算鱼竿初始倍数与鱼竿加成
        int equipCoinAddRate = DeepFishingMgr.getRodCoinAdd(userData.getFishingRodParts());
        //coin buff的总加成
        int coinBuffAddRate = 0;
        int fishCoinAddBuffId = DeepFishingMgr.getBuffIdByType(eDeepFishingBuffType.singleFishCoinAddBuff.getValue());
        if (checkBuffAdd(fishCoinAddBuffId, hasBuffList)){
            coinBuffAddRate = DeepFishingMgr.getBuffAddRate(eDeepFishingBuffType.singleFishCoinAddBuff.getValue());
        }
        BigDecimal resultCoinDecimal = BigDecimal.ZERO;
        //结算鱼类 杂物
        for (DeepFishingBagItemData bagItemData:bagResultList){
            int objectId = bagItemData.getObjectId();
            //拿配置
            DeepFishingFishConfig fishConfig = fishConfigMap.get(objectId);
            if (fishConfig == null){
                log.error("深海觅诊活动{},鱼类物品配置{}不存在",activityId,objectId);
                continue;
            }

            //鱼类处理
            if (fishConfig.getType() == eDeepFishingObjectType.fish.getValue()){
                //随机价格重量
                DeepFishingCalValueAndWeight randomValue = DeepFishingMgr.getRandomValue(objectId);
                bagItemData.setWeight(randomValue.getWeight());
                bagItemData.setValue(randomValue.getValue());
                //初始金币
                originalCoin += randomValue.getValue();
                //结算金币
                BigDecimal coinDecimal = BigDecimal.valueOf(randomValue.getValue()).multiply(BigDecimal.valueOf(equipCoinAddRate))
                        .divide(BigDecimal.valueOf(1000),0,BigDecimal.ROUND_DOWN)
                        .multiply(BigDecimal.valueOf(1000+coinBuffAddRate)).divide(BigDecimal.valueOf(1000),0,BigDecimal.ROUND_DOWN);
                resultCoinDecimal = resultCoinDecimal.add(coinDecimal);

                //增加图鉴与解锁成就
                addFishRecordToAtlas(bagItemData);
            }
            if (fishConfig.getType() == eDeepFishingObjectType.item.getValue()){

                int coin = fishConfig.getCoinRange().get(0);
                bagItemData.setValue(coin);
                originalCoin += coin;      //这里是固定金币 活动表说的

                //结算金币
                BigDecimal coinDecimal = BigDecimal.valueOf(coin).multiply(BigDecimal.valueOf(equipCoinAddRate))
                        .divide(BigDecimal.valueOf(1000),0,BigDecimal.ROUND_DOWN)
                        .multiply(BigDecimal.valueOf(1000+coinBuffAddRate)).divide(BigDecimal.valueOf(1000),0,BigDecimal.ROUND_DOWN);
                resultCoinDecimal = resultCoinDecimal.add(coinDecimal);
            }
            //钓鱼回复
            respBuilder.addFishItemData(DeepFishingPb.parseDeepFishItemToMsg(bagItemData));
        }



        //积分的buff加成
        int scoreBuffadd = 0;
        //score buff的总加成
        int buffIdByType = DeepFishingMgr.getBuffIdByType(eDeepFishingBuffType.scoreAddBuff.getValue());
        boolean scoreBuffAdd = checkBuffAdd(buffIdByType, hasBuffList);
        if (scoreBuffAdd){
            String eventValue = config.getEventConfigMap().get(buffIdByType).getEventValue();
            scoreBuffadd += StringUtils.stringToIntegerList(eventValue,"\\|").get(0);
        }


        long resultCoin = resultCoinDecimal.longValue();
        int resultScore = originalOpenScore * (1000 + scoreBuffadd ) / 1000;

        String scoreString = config.getScoreItemId() + "=" + resultScore;

        logDeepFishingFishing.setCoinReward(resultCoin+"");
        logDeepFishingFishing.setScoreReward(scoreString);

        //加积分
        player.getModule(CurrencyModule.class).addCurrency(scoreString,eLogMoneyType.DeepFishing,eLogMoneyType.DeepFishingFishingAdd);
        userData.setScoreThisActivity(userData.getScoreThisActivity() + resultScore);
        //加金币
        userData.setFishingCoins(userData.getFishingCoins()+resultCoin);
        //金币成就 排行榜
        player.notifyListener(eGamePlayerEventType.DeepFishingTotalCoinRank.getValue(),resultCoin);
        player.notifyListener(eGamePlayerEventType.DeepFishingTotalCoinProcess.getValue(),resultCoin);


        respBuilder.setCoinReward(DeepFishingMgr.getConfig().getCoinItemId()+"="+resultCoin);

        respBuilder.setScoreReward(scoreString);


        //如果是最屌的 替换之前的
        if (originalCoin > userData.getNoBuffBiggestCoin()){
            userData.setNoBuffBiggestCoin(originalCoin);
            userData.setBestAutoRecord(bagResultList);
        }

        //最后计算事件吧 再加buff
        //重置一下缓存事件
        userData.setCacheEvent(new ArrayList<>());

        if(deep > userData.getFishingReachMaxMeter()){  //如果深度变大了
            userData.setFishingReachMaxMeter(deep);
        }

        respBuilder.setRet(0);

        if (isFree){
            respBuilder.setPowerUsed(0);
        }else {
            //如果是本次钓上来的免费
            boolean checkResultFree = checkBuffAdd(noPowerBuff, hasBuffList);
            if (checkResultFree){
                userData.setFishingPower(userData.getFishingPower()+needPower);
                logDeepFishingFishing.setPowerUsed(0);
                logDeepFishingFishing.setPowerAfter(userData.getFishingPower());
                respBuilder.setPowerUsed(0);
            }else {
                respBuilder.setPowerUsed(needPower);
            }

        }
        logDeepFishingFishing.setTriggerBuff(hasBuffList);
        //buff消耗发送
        respBuilder.addAllBuffUsed(hasBuffList);
        respBuilder.addAllTriggerEvent(eventMap.keySet());

        AutoLogMgr.add(logDeepFishingFishing);
        player.sendPacket(ClientProtocol.U_DEEP_FISHING_END_GAME,respBuilder);
        syncFishingData();

        return 0;
    }

    /**
     * 随机一条钓上来过的鱼 (策划发癫弃用buff)
     */
    private int getRandomHaveFish(){
        if (userFishDataMap == null){
            return 0;
        }
        if (userFishDataMap.isEmpty()){
            return 0;
        }
        List<Integer> canRandomId = new ArrayList<>();
        for (DeepFishingUserFishData fishData: userFishDataMap.values()){
            if (fishData.getNum() > 0){
                canRandomId.add(fishData.getFishId());
            }
        }
        if (canRandomId.isEmpty()){
            return 0;
        }
        int size = canRandomId.size();
        Random random = new Random();
        int i = random.nextInt(size);
        return canRandomId.get(i);

    }


    /**
     * 图鉴与成就
     */

    private void addFishRecordToAtlas(DeepFishingBagItemData bagItemData){
        DeepFishingUserFishData fishData = userFishDataMap.get(bagItemData.getObjectId());
        if (fishData == null){      //正常改过配置才会进来吧
            fishData = new DeepFishingUserFishData();
            fishData.setUserId(getUserId());
            fishData.setIsReadSample(false);
            fishData.setFishId(bagItemData.getObjectId());
            fishData.setHeaviestWeight(0);
            fishData.setActivityId(DeepFishingMgr.getActivityInfo().getActivityId());
            fishData.setInsertOption();
            userFishDataMap.put(fishData.getFishId(),fishData);
        }
        //解锁成就 都提醒吧 不管是鱼还是啥了
//        if (fishData.getNum() == 0){
            player.notifyListener(eGamePlayerEventType.DeepFishingUnlockFish.getValue(),fishData.getFishId());
            player.notifyListener(eGamePlayerEventType.DeepFishingUnlockItem.getValue(),fishData.getFishId());
//        }
        //加数量
        fishData.setNum(fishData.getNum()+1);
        //如果最重
        if (bagItemData.getWeight() > fishData.getHeaviestWeight()){
            fishData.setHeaviestWeight(bagItemData.getWeight());
        }
        syncFishData(Collections.singletonList(fishData));
    }

    /**
     * 随机获得一条鱼的buff 后面可能改
     * @return
     */
    private int getRandomBuffFishId(){
        Map<Integer, DeepFishingFishConfig> fishConfigMap = DeepFishingMgr.getConfig().getFishConfigMap();
        List<Integer> fishIdList = new ArrayList<>();
        for (DeepFishingFishConfig fishingConfig: fishConfigMap.values()){
            if (fishingConfig.getType() == eDeepFishingObjectType.fish.getValue()){
                fishIdList.add(fishingConfig.getObjectId());
            }
        }
        Random random = new Random();
        int i = random.nextInt(fishIdList.size());
        return fishIdList.get(i);
    }

    /**
     * 玩家加个buff
     * @param buffId
     * @param times
     */

    private void addBuffToUser(int buffId,int times){
        if (userData.getFishingBuffMap() == null){
            userData.setFishingBuffMap(new ConcurrentHashMap<>());
        }
        Map<Integer, Integer> fishingBuffMap = userData.getFishingBuffMap();
        if (fishingBuffMap.containsKey(buffId)){
            fishingBuffMap.put(buffId,fishingBuffMap.get(buffId)+times);
        }else {
            fishingBuffMap.put(buffId,times);
        }
        userData.setUpdateOption();
    }


    /**
     * 检测buff加成值 同时进行buff的消耗
     */
    private boolean checkBuffAdd(int buffId,List<Integer> hasCostBuff){
        if (hasCostBuff.contains(buffId)){
            return true;
        }
        Map<Integer, Integer> fishingBuffMap = userData.getFishingBuffMap();
        boolean hasBuffAdd = false;
        if (fishingBuffMap == null){
            return false;
        }
        if (!fishingBuffMap.containsKey(buffId)){
            return false;
        }

        if (fishingBuffMap.get(buffId) > 0){
            fishingBuffMap.put(buffId,fishingBuffMap.get(buffId)-1);
            hasBuffAdd = true;
            hasCostBuff.add(buffId);
        }
        if (fishingBuffMap.get(buffId) <= 0){
            fishingBuffMap.remove(buffId);
        }
        userData.setUpdateOption();
        return hasBuffAdd;

    }

    /**
     * 同步钓鱼配置
     */
    private void syncFishingConfig(){
        if (DeepFishingMgr.getActivityInfo() == null){
            return;
        }
        DeepFishingProto.deepFishingConfigSyncMsg.Builder configMsg = DeepFishingMgr.getConfigMsg(player.getLanguage());
        player.sendPacket(ClientProtocol.U_DEEP_FISHING_CONFIG_SYNC,configMsg);

    }

    /**
     * 同步玩家图鉴信息
     */
    private void syncAllFishAtlasData(){
        if (DeepFishingMgr.getActivityInfo() == null){
            return;
        }
        if (!SystemOpenMgr.systemOpen(player,eSystemId.DeepFishing.getValue())){
            return;
        }
        if (checkNeedInitUserFishData()){
            initUserFishAtlasData();
        }
        syncFishData(new ArrayList<>(userFishDataMap.values()));
    }

    private boolean checkNeedInitUserFishData(){
        if (userFishDataMap == null){
            return true;
        }
        if (userFishDataMap.isEmpty()){
            return true;
        }
        for (DeepFishingUserFishData deepFishingUserFishData:userFishDataMap.values()){
            if (deepFishingUserFishData.getActivityId() != DeepFishingMgr.getActivityInfo().getActivityId()){
                return true;
            }
        }
        return false;
    }


    private void syncFishData(List<DeepFishingUserFishData> fishDataList) {
        DeepFishingProto.syncFishingUserFishAtlasDataMsg.Builder builder = DeepFishingProto.syncFishingUserFishAtlasDataMsg.newBuilder();
        for (DeepFishingUserFishData fishData:fishDataList){
            DeepFishingProto.deepFishingUserFishAtlasData.Builder fishBuilder = DeepFishingProto.deepFishingUserFishAtlasData.newBuilder();
            fishBuilder.setFishId(fishData.getFishId());
            fishBuilder.setHasNum(fishData.getNum());
            fishBuilder.setHeaviestWeight(fishData.getHeaviestWeight());
            fishBuilder.setIsReadSample(fishData.getIsReadSample());
            builder.addFishAtlasData(fishBuilder);
        }
        player.sendPacket(ClientProtocol.U_DEEP_FISHING_ATLAS_SYNC,builder);
    }

    /**
     * 同步玩家钓鱼消息
     */
    private void syncFishingData(){
        ActivityInfo activityInfo = DeepFishingMgr.getActivityInfo();
        if (activityInfo == null){
            return;
        }
        if (!SystemOpenMgr.systemOpen(player,eSystemId.DeepFishing.getValue())){
            return;
        }
        if (userData == null || userData.getActivityId() != activityInfo.getActivityId()){
            initUserData();
        }
        calFishingPower();
        DeepFishingProto.syncDeepFishingFishingDataMsg.Builder builder = DeepFishingProto.syncDeepFishingFishingDataMsg.newBuilder();
        builder.setFishingReachMaxMeter(userData.getFishingReachMaxMeter());

        for (Map.Entry<Integer,Integer> entry:userData.getFishingBuffMap().entrySet()){
            DeepFishingProto.deepFishingBuffData.Builder buffBuilder = DeepFishingProto.deepFishingBuffData.newBuilder();
            buffBuilder.setBuffId(entry.getKey());
            buffBuilder.setBuffTime(entry.getValue());
            builder.addFishingBuffData(buffBuilder);
        }

        for (Map.Entry<Integer,Integer> entry:userData.getFishingRodParts().entrySet()){
            DeepFishingProto.deepFishingRodParts.Builder rodPartBuilder = DeepFishingProto.deepFishingRodParts.newBuilder();
            rodPartBuilder.setPartId(entry.getKey());
            rodPartBuilder.setLevel(entry.getValue());
            builder.addFishingRodData(rodPartBuilder);
        }
        builder.setFishingCoin(userData.getFishingCoins());
        builder.setFishingPower(userData.getFishingPower());
        builder.setLastRecoveryFishingPowerTime(userData.getLastRecoveryFishingPowerTime());
        builder.setFishingGameStatus(userData.getFishingGameStatus());
        builder.setOriginalMaxAutoCoin(userData.getNoBuffBiggestCoin());
        builder.setScoreThisActivity(userData.getScoreThisActivity());
        player.sendPacket(ClientProtocol.U_DEEP_FISHING_USER_DATA_SYNC,builder);
    }

    public void syncActivity() {
        syncFishingConfig();
        if (SystemOpenMgr.systemOpen(player, eSystemId.DeepFishing.getValue())) {
            syncFishingData();      //这里判断来初始化所有
            syncBeachCombData();
            syncAllFishAtlasData();
        }
    }

    /**
     * 赶海
     */

    public int doBeachComb(int activityId,int pointId){
        if (DeepFishingMgr.getActivityInfo() == null){
            return GameErrorCode.E_DEEP_FISHING_NO_OPEN;
        }
        if (DeepFishingMgr.getActivityInfo().getActivityId()!=activityId){
            return GameErrorCode.E_DEEP_FISHING_ACTIVITY_ID_ERROR;
        }
        if (!ActivityMgr.activityInTime(DeepFishingMgr.getActivityInfo())){
            return GameErrorCode.E_DEEP_FISHING_NO_OPEN;
        }
        DeepFishingConfig config = DeepFishingMgr.getConfig();
        if (config == null){
            return GameErrorCode.E_DEEP_FISHING_BEACH_COMB_CONFIG_ERROR;
        }
        if (!DeepFishingMgr.inBeachOpenTime()){
            return GameErrorCode.E_DEEP_FISHING_BEACH_COMB_NO_IN_TIME;
        }
        //体力恢复
        calBeachCombPower();
        //检测时间刷新地图
        checkTimeRefreshBeachMap();
        //检测操作刷新地图
        checkPlayerOperateRefreshMap();

        if (userData.getBeachCombPower() < 1){
            return GameErrorCode.E_DEEP_FISHING_BEACH_COMB_POWER_NO_ENOUGH;
        }


        Map<Integer, DeepFishingBeachCombItemData> beachCombMap = userData.getBeachCombMap();
        if (!beachCombMap.containsKey(pointId)){
            return GameErrorCode.E_DEEP_FISHING_BEACH_COMB_POINT_NO_EXIST;
        }
        DeepFishingBeachCombItemData combItemData = beachCombMap.get(pointId);
        if (combItemData.isItemOpen()){
            return GameErrorCode.E_DEEP_FISHING_BEACH_COMB_POINT_HAS_OPEN;
        }
        //扣体力
        userData.setBeachCombPower(userData.getBeachCombPower()-1);

        int surplusNoOpenItemNum = getBeachCombNoOpenItemNum();
        Property property = null;

        //先判断新手引导的
        if (!userData.isTriggerGuide()){
            userData.setTriggerGuide(true);         //先取消新手教程
            int firstBeachItemId = config.getFirstBeachItem();
            property = new Property(firstBeachItemId,1);
        }else {
            //必定大奖
            if (combItemData.isSpecial()){
                property = DeepFishingMgr.getRandomBeachBigReward(pointId);
            }else { //全随机
                property = DeepFishingMgr.getRandomBeachCombReward(pointId);
            }
        }


        if (property == null){
            return GameErrorCode.E_DEEP_FISHING_BEACH_COMB_CONFIG_ERROR;
        }
        if (property.isNothing()){
            return GameErrorCode.E_DEEP_FISHING_BEACH_COMB_CONFIG_ERROR;
        }
        //判断是不是大奖
        boolean isBigReward = false;
        int scoreReward = 0;
        for (int goodId:property.getGoods().keySet()){
            if (!config.getFishConfigMap().containsKey(goodId)){
                return GameErrorCode.E_DEEP_FISHING_BEACH_COMB_CONFIG_ERROR;
            }
            DeepFishingFishConfig fishConfig = config.getFishConfigMap().get(goodId);
            //这个也要图鉴 无语
            addNewBeachItemBagItem(fishConfig.getObjectId());
            int quality = fishConfig.getQuality();
            scoreReward = fishConfig.getCoinRange().get(0);
            if (quality >=config.getHighQualityGoodThan()){
                isBigReward = true;
                break;
            }
        }
        if (isBigReward){
            userData.setBeachCombHasSpecialThisLevel(userData.getBeachCombHasSpecialThisLevel()+1);
        }
        //开盒
        combItemData.setItemOpen(true);
        //加奖励
        Property scoreRewardProperty = new Property(config.getScoreItemId(),scoreReward);
        //积分进背包
        player.getModule(CurrencyModule.class).addCurrency(scoreRewardProperty,eLogMoneyType.DeepFishing,eLogMoneyType.DeepFishingBeachComb);
        //积分进个人数据
        userData.setScoreThisActivity(userData.getScoreThisActivity() + scoreRewardProperty.getCountByGoodsId(config.getScoreItemId()).longValue());
        LogDeepFishingBeachComb logDeepFishingBeachComb = new LogDeepFishingBeachComb(getUserId(),activityId,1,
                userData.getBeachCombLevel(),pointId,PropertyHelper.parsePropertyToString(property),PropertyHelper.parsePropertyToString(scoreRewardProperty),new Date());
        AutoLogMgr.add(logDeepFishingBeachComb);
        DeepFishingProto.deepFishingBeachCombDigRespMsg.Builder builder = DeepFishingProto.deepFishingBeachCombDigRespMsg.newBuilder();
        builder.setRet(0);
        builder.setReward(PropertyHelper.parsePropertyToString(property));
        builder.setScoreReward(PropertyHelper.parsePropertyToString(scoreRewardProperty));
        player.sendPacket(ClientProtocol.U_DEEP_FISHING_BEACH_COMB,builder);

        //先检测地图是否刷新
        checkPlayerOperateRefreshMap();
        checkTimeRefreshBeachMap();
        //同步地图信息
        syncBeachCombData();
        return 0;
    }

    private void addNewBeachItemBagItem(int objectId){
        DeepFishingBagItemData itemData = new DeepFishingBagItemData();
        itemData.setValue(0);
        itemData.setWeight(0);
        itemData.setType(2);
        itemData.setOrderId(0);
        itemData.setMeter(0);
        itemData.setObjectId(objectId);
        addFishRecordToAtlas(itemData);
    }

    /**
     * 计算赶海体力是否恢复了
     */

    public void calBeachCombPower(){
        long now = System.currentTimeMillis();
        long lastRecoveryBeachCombPowerTime = userData.getLastRecoveryBeachCombPowerTime();
        if (!DateHelper.isSameDay(now/1000,lastRecoveryBeachCombPowerTime/1000)){
            int dayFreeBeachCombTime = DeepFishingMgr.getConfig().getDayFreeBeachCombTime();
            userData.setLastRecoveryBeachCombPowerTime(now);
             if (userData.getBeachCombPower() < dayFreeBeachCombTime) {
                userData.setBeachCombPower(dayFreeBeachCombTime);
            }
        }
    }

    /**
     * 计算钓鱼体力是否恢复了
     */

    public void calFishingPower(){
        CalcPowerResult calcPowerResult = PowerHelper.calcPower(userData.getLastRecoveryFishingPowerTime() / 1000, DeepFishingMgr.getMaxFishingRecoveryPowerCd(), DeepFishingMgr.getMaxFishingRecoveryPowerPerTime(), DeepFishingMgr.getMaxFishingPower(), userData.getFishingPower());
        userData.setFishingPower(calcPowerResult.getCurPower());
        userData.setLastRecoveryFishingPowerTime(calcPowerResult.getLastRecoverTime() * 1000);
    }

    /**
     * 获得赶海地图上未开启的物品个数
     */
    private int getBeachCombNoOpenItemNum(){
        Map<Integer, DeepFishingBeachCombItemData> beachCombMap = userData.getBeachCombMap();
        if (beachCombMap ==null){
            return 0;
        }
        if (beachCombMap.isEmpty()){
            return 0;
        }
        int noOpenValue = 0;
        for (DeepFishingBeachCombItemData itemData: beachCombMap.values()){
            if (!itemData.isItemOpen()){
                noOpenValue ++;
            }
        }
        return noOpenValue;

    }

    /**
     * 检测玩家操作导致刷新赶海地图
     */
    private void checkPlayerOperateRefreshMap(){
        if (userData == null){
            return;
        }
        if (userData.getBeachCombSpecialThisLevel() <= userData.getBeachCombHasSpecialThisLevel()){
            goNextBeachCombScene(false);
            return;
        }
        if (getBeachCombNoOpenItemNum() <= 0){
            goNextBeachCombScene(false);
        }
    }

    /**
     * 检测时间刷新赶海地图
     */
    private void checkTimeRefreshBeachMap(){
        //新手引导的时候不刷新
        if (!userData.isTriggerGuide()){
            return;
        }
        long now = System.currentTimeMillis();
        long beachCombLastRefreshTime = userData.getBeachCombLastRefreshTime();
        if (now <= beachCombLastRefreshTime){
            return;
        }
        //如果刷新了
        if ((now - beachCombLastRefreshTime) > DeepFishingMgr.getConfig().getBeachCombReflashCd() * DateHelper.MINUTE_MILLIONS){
            goNextBeachCombScene(true);
        }
    }

    /**
     * 进入下一场
     */
    private void goNextBeachCombScene(boolean resetTime){
        Set<Integer> set = DeepFishingMgr.getConfig().getBeachCombConfig().keySet();
        if (set.contains(userData.getBeachCombLevel()+1)){
            userData.setBeachCombLevel(userData.getBeachCombLevel()+1);
        }else {
            userData.setBeachCombLevel(1);
        }
        if (resetTime){
            userData.setBeachCombLastRefreshTime(System.currentTimeMillis());
        }
        userData.setBeachCombHasSpecialThisLevel(0);
        int specialTime = DeepFishingMgr.getRandomSpecialTime();
        userData.setBeachCombSpecialThisLevel(specialTime);
        userData.setBeachCombMap(DeepFishingMgr.generateCombItemMap(userData.getBeachCombLevel(),specialTime));
        syncBeachCombData();
    }

    /**
     * 同步赶海数据
     */
    private void syncBeachCombData(){
        if(userData==null){
            return;
        }
        if (!SystemOpenMgr.systemOpen(player,eSystemId.DeepFishing.getValue())){
            return;
        }

        DeepFishingProto.syncDeepFishingBeachCombDataMsg.Builder builder = DeepFishingProto.syncDeepFishingBeachCombDataMsg.newBuilder();
        builder.setBeachCombLevel(userData.getBeachCombLevel());
        builder.setBeachCombLastRefreshTime(userData.getBeachCombLastRefreshTime());
        builder.setBeachCombSpecialThisLevel(userData.getBeachCombSpecialThisLevel());
        builder.setBeachCombSpecialHasDrawThisLevel(userData.getBeachCombHasSpecialThisLevel());

        for (DeepFishingBeachCombItemData combItemData: userData.getBeachCombMap().values()){
            DeepFishingProto.deepFishingBeachCombItem.Builder combItemBuilder = DeepFishingProto.deepFishingBeachCombItem.newBuilder();
            combItemBuilder.setPointId(combItemData.getPointId());
            combItemBuilder.setIsOpen(combItemData.isItemOpen());
            builder.addBeachCombMap(combItemBuilder);
        }

        builder.setBeachCombPower(userData.getBeachCombPower());
        builder.setLastRecoveryBeachCombPowerTime(userData.getLastRecoveryBeachCombPowerTime());
        builder.setScoreThisActivity(userData.getScoreThisActivity());
        builder.setIsGuided(userData.isTriggerGuide());
        DeepFishingProto.deepFishingBeachCombGetNewestBeachCombDataRespMsg.Builder respMsg = DeepFishingProto.deepFishingBeachCombGetNewestBeachCombDataRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setBeachData(builder);
        player.sendPacket(ClientProtocol.U_DEEP_FISHING_GET_BEACH_DATA,respMsg);
    }


    /**
     * 检测并获取最新的赶海数据
     * @return
     */

    public int getNewestBeachData(){
        if (DeepFishingMgr.getActivityInfo() == null){
            return GameErrorCode.E_DEEP_FISHING_NO_OPEN;
        }
        if (userData == null){
            return GameErrorCode.E_DEEP_FISHING_NO_OPEN;
        }
        //算体力
        calBeachCombPower();
        //检测时间刷新
        checkTimeRefreshBeachMap();
        //检测操作刷新
        checkPlayerOperateRefreshMap();
        syncBeachCombData();
        return 0;
    }


    /**
     * 增加体力
     * @param goodsInfo
     * @param count
     */
    public void addPower(GoodsInfo goodsInfo, long count) {
        int intCount = (int)count;
        DeepFishingConfig config = DeepFishingMgr.getConfig();
        if (null != userData && config != null) {
            //如果是赶海体力
            if (goodsInfo.getGoodsId() == config.getBeachCombPowerItemId()){
                calBeachCombPower();
                userData.setBeachCombPower(userData.getBeachCombPower()+intCount);
                syncBeachCombData();
            } else if (goodsInfo.getGoodsId() == config.getFishingPowerItemId()){
                calFishingPower();
                int addCount = goodsInfo.getParamList().get(0).intValue() * intCount;
                userData.setFishingPower(userData.getFishingPower() + addCount);
                syncFishingData();
            }
        }
    }

    public void setCoins(long coins){       //todo 删！
        userData.setFishingCoins(coins);
        syncFishingData();
    }

    public void setEquipLevel(int type,int levelId){ //todo 删！
        DeepFishingEquipConfig equipConfig = DeepFishingMgr.getDeepFishingEquipConfig(levelId);
        if (equipConfig ==null){
            return;
        }
        if (equipConfig.getType()!=type){
            return;
        }
        userData.getFishingRodParts().put(type,levelId);
        syncFishingData();
    }

}
